/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package server;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author marcelo
 */
public class Server extends Thread implements java.io.Serializable {

    private final ServerSocket server;
    private Socket socket;
    private ObjectOutputStream out;
    private ObjectInputStream in;
    private Vector List;

    /**
     */
    @Override
    public void run() {
        
        this.List = new Vector();
        while (true) {
            try {
                String msg;
                socket = server.accept();
                in = new ObjectInputStream(socket.getInputStream()); //Buffer de recebimento dados
                out = new ObjectOutputStream(socket.getOutputStream()); //Buffer de envio dados
                msg = (String) in.readObject();
                switch (msg) {
                    case "NovaConexao":
                        Cliente tmp = new Cliente();
                        
                        System.out.println("Nova Conexao!");
                        System.out.println("Peer Conectado" + socket.getInetAddress().toString());

                        //Add instancia cliente à lista
                        tmp = (Cliente) in.readObject();
                        tmp.printlista();
                        this.List.add(tmp);

                        System.out.println("Fechando socket");
                        //in.close();
                        break;

                    case "Atualizar":
                        // Atualizar as listas do no x
                        long inicio1 = System.currentTimeMillis();
                        System.out.println("Atualizar peer" + socket.getInetAddress().toString());
                        tmp = new Cliente();
                        InetAddress localAddress = socket.getLocalAddress();
                        String id = localAddress.toString();

                        int j;
                        for (j = 0; j < this.List.size(); j++) {
                            Cliente test = (Cliente) this.List.get(j);
                            if (id.equals(test.getip())) {
                                System.out.println("Encontrado o peer " + String.valueOf(j));
                                break;
                            }
                        }

                        //Subst instancia cliente à lista
                        tmp = (Cliente) in.readObject();
                        tmp.printlista();
                        List.add(j, tmp);
                        long fim1 = System.currentTimeMillis();
                        System.out.println("Servidor - Tempo de Atualização: " + (fim1 - inicio1) + " milisegundos");
                        break;

                    case "Download":
                        
                        //Baixar arquivo de no x
                        long inicio2 = System.currentTimeMillis();
                        String file;
                        file = (String) in.readObject();
                        System.out.println("Nome do arquivo a ser buscado " + file);

                        Vector listfiles = new Vector();
                        int k;
                        String host;
                        String filetest;
                        Socket socket2;
                        ObjectOutputStream saidaresp;
                        String node;
                        
                        sair:
                        for (j = 0; j < this.List.size(); j++) {
                            //System.out.println("j:"+String.valueOf(j));
                            Cliente test = (Cliente) this.List.get(j);
                            listfiles = test.getlista();
                            for (k = 0; k < listfiles.size(); k++) {
                                filetest = (String) listfiles.get(k);
                                System.out.println("Arquivos buscados:"+filetest);
                                if (filetest.equals(file)) {
                                    node=test.getip();
                                    node=node.substring(1, node.length());
                                    InetAddress addr=InetAddress.getByName(node);
                                    node=addr.getHostName();
                                    node=node.substring(0,node.length()-12);
                                    System.out.println("Node:"+node);
                                    host=(socket.getInetAddress()).getHostName();
                                    host=host.substring(0,host.length()-12);
                                    System.out.println("Host:"+host);
                                    socket2 = new Socket(host, 9093);
                                    saidaresp = new ObjectOutputStream(socket2.getOutputStream());  
                                    saidaresp.writeObject(node);
                                    saidaresp.flush();
                                    saidaresp.close();
                                    break sair; 
                               }
                            }
                        }
                        long fim2 = System.currentTimeMillis();
                        System.out.println("Servidor - Tempo de Comunicação: " + (fim2 - inicio2) + " milisegundos");                        
                        break;

                    case "AtualizarConteudo":
                        String arq = (String) in.readObject();
                        System.out.println("Atualizar conteudo");
                        System.out.println(arq);
                        String cont= (String) in.readObject();
                        String no;
                        for (j = 0; j < this.List.size(); j++) {
                            //System.out.println("j:"+String.valueOf(j));
                            Cliente test = (Cliente) this.List.get(j);
                            listfiles = test.getlista();
                            for (k = 0; k < listfiles.size(); k++) {
                                filetest = (String) listfiles.get(k);
                                System.out.println("Arquivos buscados:"+filetest);
                                //Para cada Cliente verificamos as listas
                                if (filetest.equals(arq)) {
                                    no=test.getip();
                                    no=no.substring(1, no.length());
                                    
                                    InetAddress addr=InetAddress.getByName(no);
                                    no=addr.getHostName();
                                    no=no.substring(0,no.length()-12);
                                    System.out.println("Node:"+no);                                    
                                    
                                    Socket socket_node;
                                    socket_node = new Socket(no, 9095);
                                    ObjectOutputStream saida_arq;
                                    saida_arq = new ObjectOutputStream(socket_node.getOutputStream());
                                    saida_arq.writeObject("AtualizarFiles");
                                    saida_arq.flush();
                                    saida_arq.writeObject(arq);
                                    saida_arq.flush();
                                    saida_arq.writeObject(cont);
                                    saida_arq.flush();                                    
                                    
                                    
                             }
                            }
                        }                        
                        
                        break;
                        
                    case "Erro":

                        break;
                }
                in.close();
                out.close();
                socket.close();
            } catch (IOException | ClassNotFoundException ex) {
                Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
            }

        }
    }

    public Server(int port) throws IOException {
        server = new ServerSocket(port);
    }

}
